package usercenter

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"navi-mumbai/common/gensql"
	"navi-mumbai/common/key/userkey"
)

var _ UserRewardModel = (*customUserRewardModel)(nil)

type (
	// UserRewardModel is an interface to be customized, add more methods here,
	// and implement the added methods in customUserRewardModel.
	UserRewardModel interface {
		userRewardModel
		Find(ctx context.Context, uid int64, giftType int64, state int64, pageNo, pageSize int64) ([]*UserReward, error)
		UpdateState(ctx context.Context, tx sqlx.Session, id int64, state int64) error
		InsertTrans(ctx context.Context, tx sqlx.Session, data *UserReward) (sql.Result, error)
		CountNotReceived(ctx context.Context, uid int64, activityId int64) (int64, error)
	}

	customUserRewardModel struct {
		*defaultUserRewardModel
		genSql *gensql.GenSql
	}
)

// NewUserRewardModel returns a model for the database table.
func NewUserRewardModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UserRewardModel {
	return &customUserRewardModel{
		defaultUserRewardModel: newUserRewardModel(conn, c, opts...),
		genSql:                 gensql.NewGenSql(),
	}
}

func (m *customUserRewardModel) Find(ctx context.Context, uid int64, rewardType int64, state int64, pageNo, pageSize int64) ([]*UserReward, error) {
	query := fmt.Sprintf("select %s from %s ", userRewardRows, m.table)
	m.genSql.InitSql(query)

	if uid != 0 {
		m.genSql = m.genSql.Where("uid = ?", uid)
	}
	if rewardType != 0 {
		m.genSql = m.genSql.Where("reward_type = ?", rewardType)
	}
	if state != 0 {
		m.genSql = m.genSql.Where("state = ?", state)
	}

	q, v, err := m.genSql.OrderBy("create_time DESC").Limit(uint64(pageSize)).Offset(uint64((pageNo - 1) * pageSize)).ToSql()
	if err != nil {
		return nil, err
	}

	var resp []*UserReward
	err = m.QueryRowsNoCacheCtx(ctx, &resp, q, v...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (m *customUserRewardModel) UpdateState(ctx context.Context, tx sqlx.Session, id int64, state int64) error {
	q := fmt.Sprintf("UPDATE %s SET state = ? WHERE id = ?", m.table)
	_, err := tx.ExecCtx(ctx, q, state, id)
	return err
}

func (m *customUserRewardModel) InsertTrans(ctx context.Context, tx sqlx.Session, data *UserReward) (sql.Result, error) {
	query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?)", m.table, userRewardRowsExpectAutoSet)
	ret, err := tx.ExecCtx(ctx, query, data.RewardType, data.Uid, data.RewardAmount, data.ActivityId, data.State)
	return ret, err
}

func (m *customUserRewardModel) CountNotReceived(ctx context.Context, uid int64, activityId int64) (int64, error) {
	query := fmt.Sprintf("select count(id) from %s ", m.table)
	m.genSql.InitSql(query)

	q, v, err := m.genSql.Where("uid = ?", uid).Where("activity_id = ?", activityId).Where("state = ?", userkey.RewardStateCreated).ToSql()
	if err != nil {
		return 0, err
	}
	var cnt int64
	err = m.QueryRowNoCacheCtx(ctx, &cnt, q, v...)
	if err != nil {
		return 0, err
	}
	return cnt, nil
}
